home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-05-20 | 55.3 KB | 1,397 lines |
- Notes and Observations
- -
- on
- -
- IBM PC-DOS and Microsoft MS-DOS
- -
- Releases 2.0 and 2.1
- -
- April, 1984
-
-
- This document is a collection of data from various sources, including
- bulletin boards, magazines, seminar handouts, and independent research.
-
- WARNING: This information is provided without warranty of any kind. Each
- individual must determine the applicability and accuracy ofthis information
- to their specific environment.
-
- If you have corrections, additions, or comments, please send them to:
-
- John Chapman
- 844 S. Madison St.
- Hinsdale, Illinois 60521
- Or, send EMAIL to userid [70205,1217] on CompuServ,
- or MAIL to userid $AC on PCSHARE
-
- BATCH PROCESSING
-
- To modify the DOS 2.0 command interpreter so that the default is echo off
- when a batch file is run,
-
- C>debug \command.com
- -e1721 28 1f
- -e364a 24 26 c6 06 6e 09 00 e9 19 e8
- -w
- Writing 4500 bytes
- -q
-
- The DOS Environment is accessible for use in BATs.
-
- The standard keywords COMSPEC, PATH, PROMPT et al can all be read and set.
- New keywords can be set and checked within BATs. The keywords are saved
- across BAT executions.
-
- For instance BATs can check which screen is active using SET conventions as
- follows:
-
- . NOTE leading and trailing Percent signs
- IF %SCREEN% == MONO GOTO COLOR
- IF %SCREEN% == COLOR GOTO MONO
- :COLOR
- SET SCREEN=COLOR
- . NOTE no spaces around '=' in SET
- MODE CO80
- EXIT
- :MONO
- SET SCREEN=MONO
- MODE MONO
- EXIT
- . SCREEN is set and saved across BAT executions
-
- Another example using a link convention allows BATs to call BATs:
-
- *****CALL.BAT*****
-
- IF NOT %BATLABEL% == . GOTO %BATLABEL%
- . note BATLABEL is assumed to be set to '.' as a null value
- ECHO DO SOME STUFF HERE
- SET BATCALR=%0
- . give the called BAT my name to get back
- . then leave word where to come back to
- SET BATLABEL=RETURN
- . set further parms to save %1 thru %9 if necessary
- CALLED
- :RETURN
- ECHO FINISH UP HERE AFTER RETURN
-
- PC/MS-DOS Tips (2.0/2.1) 2
-
- The DOS Environment is accessible for use in BATs. (Cont'd)
-
- *****CALLED.BAT*****
-
- ECHO DO STUFF WE WERE CALLED TO DO
- . return to caller
- %BATCALR%
- . separate keywords will be necessary if further calls
- . will be made
-
-
- A note of caution (this is documented), the environment at boot time, is
- limited (I believe to only 128 bytes). If any resident modules are installed
- (i.e. PRINT, MODE, or GRAPHICS) the area cannot be expanded. You can SET
- enough variables from within AUTOEXEC.BAT to get enough space to get by.
-
- I would also recommend setting up a set of conventions and preinitializing
- the parms you'll use to '.'; Null parameters are removed from the
- environment.
-
- In summary -
- The rules are simple
- SET a parm without percent signs
- refer to them by enclosing them in percent signs
-
- I hope this discovery will generate a lot of re-thinking some BAT
- techniques.
-
- PC/MS-DOS Tips (2.0/2.1) 3
- Current MSDOS 1.xx - 2.xx Disk formats
-
- (T. Jennings 19 Aug 83)
-
- Disk Type Type Code
- .......................................................
- Single Density Single Sided 8" (SD128)
- **** Double Density Single Sided 8" (DD1024)
- **** FIDO's 8" Double Density (DD1K)
- Double Density Double Sided 8" (DD1024-2)
- IBM Displaywriter System disk (SD256)
- IBM Displaywriter System disk (DD256-2)
- IBM PC 8 Sector Single Sided (IBM8)
- IBM PC 9 Sector Single Sided (IBM9)
- IBM PC 8 Sector Double Sided (IBM8-2)
- IBM PC 9 Sector Double Sided (IBM9-2)
- Single Density Double Sided 8" (SD128-2)
-
- **** Never did get Microsoft to figure out which one these
- is the "correct" 8 inch format. Who knows.
- Type Dir Disk Fats Blk Res Sec FAT
- Code Size Size size secs size ID
- .....................................................
- SD128 68 251K 2 512 1 128 FE
- DD1K 192 660K 2 1024 1 1024 FE
- DD1024 96 612K 2 1024 1 1024 FE
- DD1024-2 192 1232K 2 1024 1 1024 FF
- SD256 80 287K 2 512 2 256 FA Note 1
- DD256-2 172 1001K 2 1024 2 256 FB Note 2
- IBM8 64 162K 2 512 1 512 FE
- IBM9 64 180K 2 512 1 512 FC
- IBM8-2 112 320K 2 1024 1 512 FF
- IBM9-2 112 360K 2 1024 1 512 FD
- SD128-2 68 2 512 4 128 FC
-
- Type trks secs res sec FAT dir 1st 2nd 1st 1st totl num.
- Code trk secs size size size FAT FAT dir data secs heads
- ......................................................................
- SD128 77 26 1 128 6 17 1 7 13 30 2002 1
- DD1024 77 8 1 1024 1 3 1 2 3 6 616 1
- DD1024-2 77 8 1 1024 2 6 1 3 5 11 1232 2
- SD256 77 15 17 256 4 10 2 6 10 20 1155 1
- Note 1
- DD256-2 77 26 54 256 6 20 2 8 14 34 4004 2
- Note 2
- IBM8 40 8 1 512 1 4 1 2 3 7 320 1
- IBM9 40 9 1 512 2 4 1 3 5 9 360 1
- IBM8-2 40 8 1 512 1 7 1 3 5 10 640 2
- IBM9-2 40 9 1 512 2 7 1 3 5 12 720 2
- SD128-2 77 26 4 128 12 17 4 16 28 45 4004 2
-
- Note 1:
- 15 sector bias in BIOS
- Note 2:
- 52 sector bias in BIOS
-
- PC/MS-DOS Tips (2.0/2.1) 4
- Additional feature in DEBUG command
-
- There is a compare feature in DEBUG that is not in the documentation. Two
- blocks of memory can be compared, byte by byte with the following command:
-
- -C AD1 AD2 AD3
-
- DEBUG will compare the memory block from AD1 to AD2 with the memory block
- starting at AD3. The results appear in a table showing both blocks side by
- side with the addresses and the corresponding contents.
-
- (from IBM.PC Users Group of Winnipeg)
-
- PC/MS-DOS Tips (2.0/2.1) 5
-
- Program File Formats
-
- The order of the segments in memory is determined by the linker; and all the
- segments are contiguous, unless you do some really determined and tricky
- hacking. Supposedly, the linker determines the order of the segments by
- putting them in "alphabetical order by segment name", or at least that's
- what the documentation says it's supposed to do; but I've found that it puts
- them in the order in which they're encountered in the program source code,
- unless you create a dummy file (see LINK instructions) with a different
- sequence and make it first in the LINK list of OBJ modules. (I generally
- put them in source in the sequence code, data, stack; they always come out
- in that order, regardless of segment names, unless I use the dummy file.
- Let's assume that sequence for the remainder of this discussion.)
-
- With an .EXE file, just before execution, the registers are as follows:
-
- AX - ostensibly per doc, zero; seems to contain the number
- of characters in the command tail, though
-
- BX:CX - 32-bit number showing load module memory size in bytes
- (good for dynamically allocating memory)
-
- DX - zero
-
- SS:SP - if you defined a stack segment, these are loaded
- accordingly; if not, SS=CS, SP=0FFFFH or end of
- memory
-
- DS and ES - SEGMENT address of "program header" (see below)
-
- CS:IP - far address of label in "END" statement of program
-
- The program header is the standard 256-byte .COM file "header", similar to
- what you would expect to see at 00-FFH in CP/M 2.x (but see doc for
- important differences!). Therefore, DS = CS - 10H (which is 100H divided by
- 10H) if the code seg is the first (owest) in memory, because it points to a
- location 100H before the start of the code seg.
-
- PC/MS-DOS Tips (2.0/2.1) 6
- Program File Formats (Cont'd)
-
- Now, if CS is, say, 9E3H when you come up, then DS and ES will contain 9D3H.
- (Remember, though, that your code thinks it starts at 9E3:0, zero being the
- address you specified in your END directive, and the instruction pointer
- will actually contain zero.) These values have nothing at all to do with
- the place at which your data seg is located; they point at that "program
- header". At location 9D3:80 (DS:80) is the command tail, if you're gonna
- reference that; its length is in AX (I believe) and is also pointed to by
- the expression DS:80 (just like CP/M; data starts at 81H), or to say it
- another way, in this case absolute memory location 09DB0 (09D30+80). But
- your code segment is, say, 400H long, and the linker knew that 'cause the
- assembler told it so in the seg, the instructions
-
- MOV AX,DATASEG
- MOV DS,AX
- MOV ES,AX
-
- (where DATASEG is the name of your data segment) will have been resolved by
- the linker in this way; the first instruction of those three was interpreted
- by the assembler as an immediate move, but the "data" to be moved into AX
- was marked as relocatable. The linker leaves instructions for the loader to
- add 9E3H (or whatever address the loader decided was a good place to put the
- program) to the value of the "constant" DATASEG, which is equal to 40H
- (400H/10H) because it's being "loaded" into a segment register, and when you
- look at that instruction under DEBUG it would say MOV AX,0A23H. (Obviously,
- this is the process of address resolution.) In absolute addresses, the
- codeseg starts at 09E30H, and the dataseg 400H later at 0A230H; in 8086
- shorthand that's 9E3:0 and A23:0 respectively. (This assumes the stackseg
- is last, say at A98:0; that would imply that your data seg was
- (0A98H-0A23H)*10H, or 750H, in length.)
-
- Almost all instructions accessing data use DS as "base" register, unless you
- override that with a prefix (as in MOV AX,ES:BLKCTR). All instructions
- accessing storage require one of the segregs as "base" register. (String
- primitives ALWAYS work with DS and/or ES and can't be overridden by a
- prefix; instructions using BP as an "index" are relative to SS, unless
- overridden by a prefix; otherwise, it's DS when not overridden. Be
- careful!)
-
- PC/MS-DOS Tips (2.0/2.1) 7
-
- Program File Formats (Cont'd)
-
- In BAL, you give the assembler a USING statement; that tells it that offsets
- will be computed relative to the first operand of the USING statement, and
- tells it to use the second operand as "base" register in base+offset
- instructions. The code won't work properly until you load the address of
- the first operand into the register named by the second operand. In 8086,
- you give the assembler an ASSUME statement; for instructions using CS as
- "base" (segment) register (all of them), such offsets will be calculated
- from the point named as xyz in the statement "ASSUME CS:xyz, DS:abc,ES:def";
- for instructions which use DS (such as MOV AX,BLKCTR), the value of the
- offset of BLKCTR is computed relative to label abc; for ES instructions
- (when you use a segment override prefix, as in MOV AX,ES:BLKCTR), offset is
- computed relative to "def". Then, if you hav that (for example) DS:offset
- points to the absolute location of BLKCTR, you'll be moving something random
- into your AX register. With .COM files, CS=DS=ES at startup; note that a
- typical .COM file ASSUME statement looks like ASSUME
- CS:CODESEG,DS:CODESEG,ES:CODESEG,SS:CODESEG (whoops, one more)
-
- But as you can see from the preceding stuff, with .EXE files DS and ES start
- out with values which don't point at your data at all. You have to do
- something like MOV AX,abc!MOV DS,AX!MOV ES,AX to put coherent values into
- the segregs, just as you have to do something like BALR 4,0!BCTR 4,0!BCTR
- 4,0 to put a coherent value into the base reg in BAL. That is, with an .EXE
- file, you tell the assembler to use DATASEG as the reference point to
- compute an offset from (with the ASSUME statement); and then you must make
- sure you load DS with a value that will, in combination with the computed
- offset, point at the right data.
-
- One more example, then I'll stop. Let's take a BAL program and specify a
- code "segment" 4096 bytes long, a data "segment" 4096 bytes long, and a
- "stack segment" after that. In order to be able to access all of that data
- in that way, you'd need three base registers; let's use 3, 4 and 5. With
- BAL, you have to figure the addresses yourself, so we get something like:
-
- PGM START 0 BEGIN STM 14,12,12(13)
- BALR 3,0
- DTSEG EQU START+4096
- STSEG EQU START+8192
- USING *,3
- USING DTSEG,4
- USING STSEG,5
- START ST 13,SAVEAREA+4
- LA 13,SAVEAREA
- LA 4,4096(3)
- LA 5,8192(3)
- That is, if I remember my BAL. You get the idea.
-
- PC/MS-DOS Tips (2.0/2.1) 8
-
- The CTTY Command and Basic Feature
-
- (from Tom Jennings)
-
- The DOS manual explains that the command is simply CTTY device-name. This
- will transfer control from the keyboard and screen to that device. It
- suggests that LPT1: is not a ood idea since the printer communicates
- (mostly) one way. What this really leaves is COM1:, COM2: and AUX: I very
- cleverly tried typing CTTY COM1: It does do something, it kills the keyboard
- and a cold BOOT is necessary to restart. Well, that wasn't it. Something
- must occur prior to the CTTY command. Being strickly a seat-of-the-pants
- type, I set the HAYES to ANSWER and called in. Nice, I had a connection
- (CARRIER/carrier). I rushed over to the PC keyboard and typed CTTY COM1:
- and the screen went dead. So, what else is new....But, on my other SYSTEM,
- (other end of the office), the prompt A> appeared. I sat and typed on the
- terminal just as though I was sitting in front of the IBM.
-
- Well, what do you know?
-
- 1) Commands are limited to what the terminal keyboard can reproduce i.e. ^C
- for CTRL-BREAK but not CTRL-ALT-DEL (as if you would want that one anyway).
-
- 2) Going to BASIC cuts you off. SYSTEM control returns to the keyboard.
-
- 3) Most commands work except COPY as it relates to CON: or COM1: COPY from
- disk to disk worked O.K.
-
- 4) This means is total control from outside while in DOS only on a
- line-by-line basis. Anything which relies on screen mapping will not work.
- (Run Norton's DISKMAP from the terminal and the map appears on the PC
- screen.)
-
- You may be wondering why all this verbage. Well.... the result of my
- efforts is a BASIC program called RING.BAS which will set up the HAYES to
- patiently look for an incoming ring, and very politely turn SYSTEM control
- over to the caller. Oh, I forgot to mention the BASIC program must be
- called from a BATCH file called OUTSIDER.BAT. When RING goes back to the
- SYSTEM, the next command is CTTY COM1: Slick, huh? RING will even write the
- BATCH file for you. Just take a look at the internal documentation for
- additional information.
-
- Note: Tom Jenning's 'FIDO' board is at (415) 864-1418
-
- PC/MS-DOS Tips (2.0/2.1) 9
-
- DOS 2.0 HAS PROBLEMS WITH REDIRECTION OF I/O
-
- There are problems in DOS 2.0 with the redirection of I/O and piping for
- programs that use the original DOS 1.1 INT 21 function calls for input.
- This problem is readily apparent to users of C language packages such as
- Computer Innovation C-86, Lattice C, or Microsoft C (you'd think they would
- get it right!). One problem is that all output to the screen is redirected,
- even keyboard echo. Correct operation would redirect all program output for
- the screen (stdout) to the specified >file, but the echo of keyboard input
- would still be sent to the screen. Instead, both the keyboard echo and the
- program output are sent to the redirected >file. Thus, if you run programs
- such as the CAT.C (K&R,page 154) example that Microsoft distributes with
- their C; or COPYIO.C (K&R,page 15) with the output redirected to a file, you
- will get the following results:
-
- 1. Under DOS 1.1, keyboard input is echoed to the screen as you type and
- each line appears in the >file once as expected.
-
- 2. Under DOS 2.0, keyboard input is not echoed to the screen, but each line
- appears in the >file twice!
-
- This situation is handled correctly in DOS 2.0 if the new INT 21 function
- call 3F is used. This can be demonstrated by redirecting output for the DOS
- 2.0 function MORE - it works as desired.
-
- The redirecting of input to these programs doesn't work properly either. If
- the file has not been edited with debug to end with a control-Z, the program
- will hang up at the end of the <input file. You must reboot the system to
- continue! Also, if you pipe the output of the first program into a second
- program, the final output will contain each line four times, doubled spaced
- after the second lie! These problems do not occur for programs that use the
- new DOS 2.0 calls for I/O, such as SORT and MORE.
-
- The question now is how do you fixup C programs to run under DOS 2.0
- and not redirect keyboard echo to the stdout file? The easiest way for C
- compilers that include their own redirection code is to change their
- redirection symbols from <, >, and >> to something else. Then DOS 2.0 won't
- do the redirection, so the C code will be able to do it correctly. With the
- Microsoft C compiler, this is easily accomplished by modifying three lines
- of code in MAIN.C. A good choice is to modify MAIN.C so that it redirects
- on the symbols {, , and . The only restriction is that these symbols then
- should not be used in filenames. With these changes, the user can choose to
- let either DOS <, >, >> or C {, . do the redirecting. The modified version
- of MAIN.C is compiled to obtain a new MAIN.OBJ, which can either be put into
- the library MC.LIB to replace the original MAIN by using the LIB.EXE
- utility, i.e. LIB MC.LIB MAINMAIN or it can be kept separate. If kept
- separate, remember to include it in the list of .OBJ files specified in the
- LINK call, i.e. LINK cmain myprogram.
-
- The three lines to change in Microsoft C's MAIN are:
- case '{':
- case ' ':
- if (*line == ' ')
-
- PC/MS-DOS Tips (2.0/2.1) 10
-
-
- The following is a summary of some undocumented DOS 2.0 functions
- which can be invoked through interrupt 21H. The information provided herein
- have inaccuracies, so use it at our own risk! It is correct to the best of
- my knowledge. See the section in your DOS 2.0 manual entitled "Invoking DOS
- Functions" for further information. The function number provided below for
- each operation is to be placed in the AH register as described in the DOS
- manual. All numbers shown are in hex.
-
- FUNCTION DESCRIPTION
-
- 37 This interrupt is used to change incompatible
- configuration parameters to allow for switch
- indicators and whether hardware devices are
- available at every level of the tree directory.
-
- Usage: MOV AH, 37
- MOV AL, func ; function code
- MOV DL, data
- INT 21H
- ; read function data is returned in DL
-
- Function code for AL:
- 0 - Return the DOS switch character in DL.
- Many systems might return "-".
- 1 - Make the character in DL the switch character.
- 2 - Read the device availability byte into DL. A
- 0 means devices that devices must be accessed
- in file I/O calls by /DEV/device. A non-zero
- value means that devices are accessible at
- every level of the directory tree (e.g., PRN
- is the printer and not a file PRN).
- 3 - Set the device availability byte to the
- contents of DL.
-
- Possible errors returned in AL:
- FF - Illegal function code specified in AL.
-
- 1F (?) Retrieve the pointer to the default drive parameter block.
-
- Usage: MOV AH, 1F
- INT 21H
- ; address of drive parameter block is returned in DS:BX
-
- PC/MS-DOS Tips (2.0/2.1) 11
- 32 (?) Retrieve the pointer to the drive parameter block
- for the drive number in DL, where 0 = default drive,
- 1 = drive A:, 2 = drive B:, etc.).
-
- Usage: MOV AH, 32h
- MOV DL, drivenum
- INT 21H
- ; address of drive parameter block is returned in DS:BX
- ; AL contains FF if the drive # in DL is invalid.
-
- F8 (?) Set OEM handler for INT 21H calls from F9 through FF
- to DS:DX. To reset these calls, pass DS and DX with FFFF.
- DOS is set up to allow ONE handler for all 7 of these
- calls. Any call to these handlers will result in the
- carry bit being set and AX will contain 1 if they are
- not initialized. The handling routine is passed all
- registers just as the user set them. The OEM handler
- routine should be exited through an IRET.
-
- Usage: LDS DX, handleaddr
- MOV AH, F8h
- INT 21H
- 4B Load and possibly execute a program (EXEC). This call
- is PARTIALLY documented in the IBM DOS 2.0 manual, but
- several function call values (for register AL) are
- omitted. They are:
-
- 1 - Create the program segment prefix and
- load the program, but do not begin
- execution. The CS:IP and SS:SP of the
- program are placed in the area provided
- by the user.
-
- +-------------------------------+
- | Word segment addr of environ. |
- +-------------------------------+
- | Dword ptr to cmd line at 80h |
- +-------------------------------+
- | Dword ptr to default FCB to |
- | be passed at 5Ch. |
- +-------------------------------+
- | Dword ptr to default FCD to |
- | be passed at 6Ch. |
- +-------------------------------+
- | Dword value of SS:SP returned |
- +-------------------------------+
- | Dword value of CS:IP returned |
- +-------------------------------+
-
- 2 - This function still remains a mystery.
- PC/MS-DOS Tips (2.0/2.1) 12
-
- 4E Find first matching file (FIND FIRST). This function
- is PARTIALLY documented in the IBM DOS 2.0 manual.
- The description of what is returned in the DTA where
- the first 21 bytes are "reserved for DOS use on
- subsequent find next calls" contain the following
- in this order:
-
- 1 byte - attribute byte of search
- 1 byte - drive used in search
- 11 bytes- The search name used
- 2 bytes - Word value of last entry
- 4 bytes - Dword pointer to this DTA
- 2 bytes - Word directory start
- -----------------------------------
- { The documented bytes follow here
- such as attribute found, file's
- time, date, size, and name found.
-
-
- 50 Define the current DTA (?) - this is all I know...
- 51 Retrieve current DTA (?)
- 52 Retrieve "IVARS" (?)
- 53 Define something about a DTA (?)
- 55 Duplicate a DTA (?)
-
- The DOS critical section flag may be interrogated from within an
- interrupt handler before requesting DOS services:
-
- MOV AH,34h
- INT 21h
-
- returns in ES:BX the address of a byte indicating (when set) that DOS
- is in an uninterruptible state, and no DOS calls should be made.
-
- PC/MS-DOS Tips (2.0/2.1) 13
-
- To access DOS' PRINT capabilities:
- MOV AH,func
- INT 2Fh
- Where:
-
- AH = 0 adds the file specified by DS:DX to the
- print queue. DS:DX must point to valid
- opened FCB.
-
- AH = 1 cancels the file indicated by DS:DX.
- DS:DX must point to an FCB, opened or
- unopened. The drive byte must not be 0.
- Wildcards are restricted: ? is okay, *
- isn't.
-
- AH > 1 do nothing.
- Return with registers set as follows:
- DS,SI,DI,CX preserved, all others destroyed.
- AH = number of files currently in queue.
- AL = for AH=0, return 1 if queue was
- full. For all other cases, return 0.
- ES:BX = pointer to list of 10 FCBs in
- queue, 38 bytes/FCB. If the first
- byte of an FCB is -1, that FCB is
- unused.
-
- ES:DX = pointer to currently printing
- FCB. If the queue is empty, DX = -1.
-
- PC/MS-DOS Tips (2.0/2.1) 14
- An Operating System Dialog - PC/MS-DOS
-
- This is a list of PCDOS and MSDOS peculiarities, etc. You will
- have to guess from the text what the particular questions were, but you
- systems programmers will find it worth your while to rummage through it all.
-
- There is a problem of compatibility between MS-DOS and IBM PC-DOS having
- to do with FCB Open and Create which has finally been tracked. The IBM 1.0,
- 1.1, and 2.0 documentation of OPEN (call 0FH) contains the following
- statement.
-
- "The current block field (FCB bytes C-D) is
- set to zero [when an FB is opened]."
-
- This statement is NOT true of MS-DOS 1.25 or MS-DOS 2.00. The difference
- is intentional, and the reason is CP/M 1.4 compatibility. Zeroing that
- field is not CP/M compatible. Some CP/M programs will not run when machine
- translated if that field is zero ed. The reason it is zeroed in the IBM
- versions is that IBM specifically requested that it be zeroed. This is the
- reason for the complaints from some vendors about the fact that IBM
- MultiPlan will not run under MS-DOS. It is probably the reason that some
- other IBM programs don't run under MS-DOS.
-
- PROGRAMMERS NOTE:
-
- Do what all MS/PC-DOS Systems programs do: Set every single FCB
- field you want to use regardless of what the documentation says is
- initialized.
-
- a) It seems there is a maximum of 19 handles, no matter what the
- files parameter is set to. Is this really the case? What does one gain by
- setting files to less than 19? Is memory for handles allocated dynamically?
-
- There is a maximum of 20 handles per process no matter what the
- files parameter is set to. There has to be a table in your process header
- for your handles, there is a limited amount of space down there. 40 bytes
- or so are taken up by each system FCB, setting files to less than 20 saves a
- little bit of memory. Memory for handles is not allocated dynamically, in
- general an attempt to do so would fail anyway. Recall that .COM files and
- most .EXE files are given the biggest piece of memory possible w hen they
- are EXECed because the DOS cannot make assumptions about how much memory
- these programs really use. This means they typically get ALL of the free
- memory, that means there is no free memory to allocate dynamically. You
- will find that almost a ll operating systems (CP/M is about the only
- exception) have a limit on the number of open files. MS-DOS has a limit of
- 20. CP/M has no such limits because it requires the user to keep FCBs in
- his own address space, managing FCBs is a pain. You get si mplicity and you
- give up very little. What program needs more than 20 open files? If you
- can think of one, it is probably a poorly written program in that it
- probably only needs a few open files at a time and doesn't bother to close
- files after it's d one with them.
-
- PC/MS-DOS Tips (2.0/2.1) 15
-
- b) Execing a program eats 5 (I think) handles per try. Is this the
- passing of parent's environment that is mentioned (very briefly) in the
- documentatio n? What are these handles? They don't seem to be allocated
- with system calls, either. Is that true? std-in, std-out, std-err,
- std-aux, std-prn. I suppose you would like your program to be able to use
- the 1-12 system calls? That means there have to be 5, the first three are
- standard UNIX style fair and are required for the software tools approach to
- programming. Std-aux and Std-prn are required for system calls 3,4, and 5.
- Just because you are handed these default handles doesn't mean you can't
- close them.
-
- "... 1) what exactly is meant by the dos being in an unstable state.
- (This is what the documentation says happens if one returns to a user
- program directly from an int 24 handler.)..."
-
- It means that the DOS has the notion of an error being in effect. All
- printer echoing is turned off, and some other stuff doesn't work. Also,
- there are dirty buffers that are not correctly flushed out. Thus the disks
- may not be consistent.
-
- "... 2) my experimentation shows that an abort from a hard error
- handler causes an int 22 without the value for int 22 being sucked out of
- the program header. every other way out of a program uses he terminate
- address in the header. is this difference intentional? Why? DOes one
- expect the value at int 22 to be different from the value in the header
- ever?..."
-
- False. No INT 22h is ever issued. The header is only used to save the
- previous process' vectors. The address contained in INT 22 is saved in a
- temp spot, the contents of INTs 22-24 are restored from the header, and then
- an indirect jump is taken th rough the temp location. Certain programs
- (such as COMMAND) may want to intercept themselves from terminawill then
- attempt to write it out, causing a write-protect error. If you catch the
- INT 24 and do not return, the dirty b uffer still exists. To clear out the
- dirty buffer, you MUST return from the INT 24 saying to abort the process.
- You can then catch the terminate and restore your stack (you will be running
- on your parent's stack).
-
- "... 1) Why does PCDOS exec function 3 (overlay) demand that there
- be some free memory that it can allocate...."
-
- It doesn't. IBM specifically requested that the Exec code be overlayable
- in the MSDOS. As a result, it lives in the transient piece of COMMAND.COM
- and gets loaded when needed: thus the requidement for enough free space to
- laod the Exec loader (about 1.5K).
-
- Under other MSDOS's there is no such problem as the Exec system call
- lives in system space. A general rule of thumb is: if you are not going to
- use some space, free it. You can do this either via SetBlock system call,
- or by twiddling the EXE file he ader. You should avoid .COM format files.
-
- PC/MS-DOS Tips (2.0/2.1) 16
-
- "... what happens if I try to overlay an .EXE file with the high/low
- switch set to load the thing for high memory..."
-
- Nothing. The HIGH/LOW switch is only for process creation, not for
- overlays.
-
- "... Are all these answeres the same for MSDOS?..." [Yes.]
-
- "... zeroing of the current record field ..."
-
- That incompatability existed between 1.1 PC-DOS and 1.25 MSDOS. 2.0
- versions of both function identically (like 1.1 PC-DOS).
-
- The Shell command on PC-DOS 2.0 works just fine.
-
- CONFIG.SYS
- shell = b:\command.com b:\ /P
-
- Putting a disk with command.com in drive B: when the system boots causes
- COMMAND to be read from drive B: and the COMSPEC in the environment is
- "B:\COMMAND.COM". If you are having trouble it's because you are doing
- something wrong. Recall that your g iven COMSPEC is checked, if you give it
- a bad one it will try to go back to the default which is the root directory
- on the default drive. Recall also that this is an undocumented 2.0 feature
- so even if it doesn't work nobody is going to be all that ho t to do
- something about it.
-
- My error on the shell stuff, IBM hid it real well. The "b:\" is also
- documented on page 10-9 (the [d:][path] part). They did an equally poor job
- here.
-
- The /P and the path spec have absolutely nothing to do with the SHELL
- command, they are arguments to command. Expecting SHELL to know stuff
- particular to command is not reasonable because you are not restricted to
- running command as your top level she ll. You can run DEBUG as your top
- level shell by saying
-
- SHELL = debug.com
-
- But watch out!! debug is not designed to run as a top level shell. if
- you ever say "q" to this debug the system will crash. Command on the other
- hand is smart enough to run as a top level shell. If you give the /P switch
- to it Command does some specia l things to insure that typing EXIT to it
- will not cause the system to crash as with debug. There is absolutely no
- way for command to assume the /P switch because he must run as a top level
- shell, and as a utility. The smart user has to tell him what to do.
- Similarly the "b:\" tells command where to look for himself. For instance:
-
- SHELL = A:\BIN\COMMAND.COM D:\COMMAND\BIN /P
-
- The "A:\BIN\COMMAND.COM" tells SYSINIT where to load the initial
- command.com, the "D:\COMMAND\BIN" tells command where to look for himself
- when he needs to locate his transient. As you can see they are not
- restricted to being the same things. I suggest you foreward any complaints
- about the manual to [no address given]
-
- PC/MS-DOS Tips (2.0/2.1) 17
-
- The volume ID attribute is very special, and is treated differently from
- all the other attributes. It is very "sticky", in order to find one you
- must look for it and it alone. And when you do look for it, you find only
- it and nothing else.
-
- The volume ID is constrained to be in the ROOT directory, and there can
- be only one file in the ROOT with the attribute. The FCB flavor calls have
- special code to enforce these rules.
-
- The new calls were supposed to enforce the same rules, but they are not
- working correctly, and unexpected results are possible. You should use the
- old FCB calls to diddle with volume ID for the moment.
-
- Thanks for the info. The causes of your problems are:
-
- (a) ^Z on output to a device in cooked mode will terminate the output.
- This is for CPM-compatability: you don't want stuff after the ^Z output to
- your printer for example.
-
- As a result COMMAND.COM issues a write to stdout and then checks to
- see if the number written is equal to the number requested. If they are not
- the same, then a redirection error is assumed. ECHO ^Z is supposed to
- output a single cha racter. It outputs NO characters and thus the strange
- message.
-
- Programs that use old function calls, get redirected, and then read
- more than is expected will behave bizarrely: how do you indicate EOF on a
- read-byte-from- console system call? I believe that it returns ^Z. Most of
- these programs we re never expecting to get redirected and thus, the failure
- to handle the boundary conditions properly.
-
- (b) The main crock about CP/M is that the extention on a file name
- determined the type of the file. This is bogus: a file should be
- distinguished by its contents, not by its name. When you are loading a file
- with the name *.EXE, it d oes NOT assume that it is an EXE format file. It
- looks at the first two bytes for a signature telling it that it is an EXE
- file. If it has the proper signature, then the loa proceeds. otherwise, it
- presumes the file to be a COM- form at file.
-
- If the file has the EXE signature, then the internal consistency IS
- checked.
-
- Pre-2.0 versions of MSDOS did not check the signature byte for EXE
- files.
-
- PC/MS-DOS Tips (2.0/2.1) 18
- ;This routine implements the UN*X system call (in spite of the fact that I
- ;called it exec, the name in the DOS manual) under Lattice C although it
- ;should be easy to adopt it to other languages. One caution, it uses the
- ;undocumented 037h DOS call to retrieve the switch character. This is
- ; marked in the code and I will change it after DOS 2.0 so I'd rather
- ;the DOS purists don't jump down my throat about this. If you don't like it
- ;the way it is, change it.
- ;
- ;
- ; Darrell Plank
- ; BTL-IH
- PAGE 55,132
- ;
- ; This function is modified from the macro by Brad Davis (b-davis@utah-cs)
- ; The prolog and epilog are modified from Jim Holtman's macros for Pascal.
- ;
- ; exec( cmd)
- ; char *md;
- ;
- ; This function accepts a string with the pathname of a command to be
- ; executed and executes it. The returned value is one of the following:
- ; 0: Successful
- ; -1: Insufficient Memory
- ; -2: Access Denied
- ; -3: No such command
- ; -4: Invalid command format
- ;
-
- PROLOG MACRO
- PUSH BP
- MOV BP,SP
- ENDM
-
- EPILOG MACRO NUM
- POP BP
- RET
- ENDM
-
- PC/MS-DOS Tips (2.0/2.1) 19
-
- EXECVAL EQU 0
- OVLVAL EQU 3
- FNCINT EQU 21H
- SETBLK EQU 4AH
- EXECF EQU 4BH
- CR EQU 0DH
-
- PSP STRUC
- INTVECT DW ?
- TOM DW ?
- RES1 DB ?
- DOSLONG DB 5 DUP (?)
- TERMINA DD ?
- CTRLBRK DD ?
- CRITERR DD ?
- DOS1 DB 22 DUP (?)
- ENVIRO DW ?
- DOS2 DB 46 DUP (?)
- FPA1 DB 16 DUP (?)
- FPA2 DB 20 DUP (?)
- UPA DB 128 DUP (?)
- PSP ENDS
-
- EXECDEF STRUC
- NENVIRO DW
- COMMND DW 2 DUP (0)
- FCB5CH DW 2 DUP (0)
- FCB6CH DW 2 DUP (0)
- EXECDEF ENDS
-
- PC/MS-DOS Tips (2.0/2.1) 20
-
- PGROUP GROUP PROG
- PROG SEGMENT BYTE PUBLIC 'prog'
- ASSUME CS:PGROUP
-
- PUBLIC EXEC
- EXEC PROC NEAR
- PROLOG
- PUSH DS
- PUSH ES
- ;
- ; free up as much memory as we can
- ;
- MOV AX,CS
- PUSH ES ; Save ES for later
- MOV ES,AX
- MOV BX,SS
- SUB BX,AX
- ADD BX,1000H ; 64K for stack segment
- MOV AH,SETBLK
- INT FNCINT
- JNC NEAR PTR LBL1
- MOV AX,-1 ; Insufficient memory
- JMP NEAR PTR FINE
- LBL1: POP ES ; Get ES's original value
- ;
- ; Save SS and SP registers
- ;
- MOV CS:SPSAVE,SP
- MOV CS:SSSAVE,SS
- ;
- ; set up the parameter block
- ;
- MOV CS:EXECBLK.NENVIRO,0 ; Inherit envir. from parent
- MOV AX,3700H ; Undocumented call for SWITCHAR
-
- PC/MS-DOS Tips (2.0/2.1) 21
-
- ; W A R N I N G: The following function call is undocumented and is
- ; liable to disappear or change in future versions of DOS.
- INT FNCINT
- MOV CS:COMMAND[1],DL ; Switchar
- MOV DX,4[BP] ; Address of the command
- MOV SI,DX
- MOV DI,DX
- CLD
- XOR AL,AL
- MOV CX,100H ; Longest string can be 100h
- REPNE SCASB ; Find Null termination
- SUB DX,DI
- NEG DX
- MOV CX,DX
- DEC CX
- ADD DX,2
- MOV CS:COMMAND[0],DL ; Save command length
- LEA DI,CS:COMMAND[4]
- MOV AX,CS
- MOV ES,AX
- REP MOVSB ; Copy command into our buffer
- ASSUME DS:PGROUP
- MOV AX,CS
- MOV DS,AX ; DS points at code segment
- MOV BYTE PTR [DI],CR ; Put in Carriage Return
- LEA DX,COMMAND
- MOV EXECBLK.COMMND[0],DX
- MOV EXECBLK.COMMND[2],DS
- MOV BX,OFFSET EXECBLK
- XOR SI,SI
- MOV DS,[SI].ENVIRO ; Get environment address
- ASSUME DS:NOTHING
- LEA SI,CS:COMSPEC ; Point SI at env. variable name
- PUSH DS ; Swap
- PUSH ES ; ES
- POP DS ; and
- POP ES ; DS
- CALL GETENV
- PUSH DS ; Swap
- PUSH ES ; them
- POP DS ; back
- POP ES ; again
- MOV AH,EXECF
- MOV AL,EXECVAL ; OVLVAL here for overlay
- INT FNCINT
- JC NEAR PTR LBL2
- MOV AX,0 ; Successful exec
- JMP NEAR PTR FINE
- LBL2: MOV SI,AX
- MOV AL,CS:ERRORS[SI] ; Get error code
- MOV AH,0FFH ; Sign extension - Assume Negative
- FINE: MOV SS,CS:SSSAVE
- MOV SP,CS:SPSAVE
- POP ES
- POP DS
- EPILOG 1
-
- PC/MS-DOS Tips (2.0/2.1) 22
-
- EXECBLK EXECDEF <>
- ;
- ; first byte of command s length excluding the length byte and the
- ; trailing \r. Second byte is switchar.
- ;
- COMMAND DB 2 DUP(?),"C ",254 DUP(?)
- COMSPEC DB "COMSPEC",0
- SPSAVE DW
- SSSAVE DW
- ERRORS DB ?
- DB ?
- DB -3 ; No such command
- DB ?
- DB ?
- DB -2 ; Access denied
- DB ?
- DB ?
- DB -1 ; Insufficient memory
- DB ?
- DB ?
- DB -4 ; Invalid command format
-
- EXEC ENDP
-
- ;
- ; Getenv expects ES to have the environment paragraph and DS:SI to point
- ; to an ASCIIZ string with the desired environment variable in it.
- ; It returns the address of the proper string in ds:dx.
- ;
-
- PUBLIC GETENV
- GETENV PROC NEAR
-
- PROLOG
- PUSH AX
- PUSH CX
- PUSH SI
- PUSH DI
- MOV CS:VARNAME,SI ; Save offset of env. name
- XOR DI,DI
-
- PC/MS-DOS Tips (2.0/2.1) 23
-
- ;
- ; At this point ds:si points to dummy variable environment name and
- ; es:di points to environment.
- ;
- CLD ;Forward string operations
- TOP:
- LODSB ;Get a char. of env. name
- CMP AL,0 ;If we're at the end
- JNE NEAR PTR LBL3
- CMP BYTE PTR ES:[DI],'=' ;Check for match
- JNE NEAR PTR LBL4
- ;
- ; We matched
- ;
- INC DI ;Move beyond '='
- MOV DX,DI
- POP DI
- POP SI
- POP CX
- POP AX
- EPILOG 2
- LBL4:
- ;
- ; At this point we found the end of the Env. variable name but it didn't
- ; match because the env. string was too long
- ;
- MOV CX,-1
- REPNE SCASB ;Find the end of the env. string
- CMP BYTE PTR ES:[DI],0
- JNE LBL3
- MOV AX,-1 ;End of evironment area
- POP DI
- POP SI
- POP CX
- POP AX
- EPILOG 2
- PC/MS-DOS Tips (2.0/2.1) 24
-
- LBL3:
- ;
- ; Check if the next character matches
- ;
- AND AX,11011111b ;Capitalize the character in ax
- SCASB
- JE TOP
- ;
- ; If we get here we don't have a match so move on
- ;
- MOV SI,CS:VARNAME ;Go back to start of env. string
- XOR AX,AX
- MOV CX,-1
- REPNE SCASB ;Go to next env. variable
- CMP BYTE PTR ES:[DI],0
- JNE TOP
- MOV AX,-1 ;End of environment area
- POP DI
- POP SI
- POP CX
- POP AX
- EPILOG 2
-
- VARNAME DW ?
-
- GETENV ENDP
-
- PROG ENDS
- END
- [This program will be kept in <INFO-IBMPC> as EXEC.ASM -ed]
-
- PC/MS-DOS Tips (2.0/2.1) 25
- +----------------------------------------------------------------------------+
- | D O S 2 . 1 I N T E R R U P T 2 1 F U N C T I O N C O D E S |
- +----------------------------------------------------------------------------+
- +----+--------------------------+-----------------------+--------------------+
- | AH | F U N C T I O N | Entry / Register Use | N O T E S |
- +----+--------------------------+-----------------------+--------------------+
- | 00 | Program terminate | CS=PSP seg. addr. | Exit vectors are |
- | restored |
- | 01 | Keyboard input | N/A: returns AL | waits for a char; |
- | echoes it |
- | 02 | Display output | puts DL | break checked for |
- | 03 | AUX (Asynch) input | N/A: returns AL | Unbuffered,
- | non-interrupt |
- | 04 | AUX (Asynch) output | puts DL | " " |
- | 05 | Printer output | puts DL | |
- | 06 | Direct CON: I/O | DL=FF input | ZF set for no input|
- | 07 | Direct CON: input Noecho | N/A: returns AL | |
- | 08 | Console input Noecho | N/A: returns AL | Same as Fctn 1 |
- | except no echo |
- | 09 | Print string | DS:DX ==>string | string terminator $|
- | 0A | Buffered keyboard input | DS:DX ==>buffer | 1st byte is length |
- | 0B | Check std. input status | AL=FF if input | AL=00 if no input |
- | 0C | Clear kybd buf. + other | AL = function no. | fctns 1,6,7,8,A |
- +----+--------------------------+-----------------------+--------------------+
- | 0D | Disk reset | N/A | Flushes all buffers|
- | 0E | Select disk | DL=drive no. | AL=no drives |
- | | on system |
- | 0F | Open file | DS:DX ==> FCB | AL=FF for error |
- | 10 | Close file | DS:DX ==> FCB | AL=FF for error |
- | 11 | Search for first entry | DS:DX ==> FCB | AL=FF for no match |
- | 12 | Search for next entry | DS:DX ==> FCB | must follow fctn 11|
- | 13 | Delete file | DS:DX ==> FCB | AL=FF for error |
- | 14 | Sequential read | DS:DX ==> FCB | EOF = 01 or 03 |
- | 15 | Sequential write | DS:DX ==> FCB | AL=01 (full) |
- | | 02 (bad buffer) |
- | 16 | Create file | DS:DX ==> FCB | AL=FF |
- | directory full |
- | 17 | Rename file | DS:DX ==> FCB | AL=FF for error |
- | 18 | Used internally by DOS: | | |
- | 19 | Current disk | N/A: returns AL | |
- | 1A | Set DTA | DS:DX ==> new DTA | |
- | 1B | Get FAT (default drive) | N/A: returns DS:BX | FAT id byte for |
- | | default drive |
- | 1C | Get FAT (select drive) | N/A: returns DS:BX | FAT id byte for DL |
- | 1D | Used internally by DOS: | | |
- | 1E | Used internally by DOS: | | |
- | 1F | Used internally by DOS: | | |
- | 20 | Used internally by DOS: | | |
- | 21 | Random read | DS:DX ==> FCB | AL=00 good read |
- | 22 | Random write | DS:DX ==> FCB | AL=00 good write |
- | 23 | File size | DS:DX ==> FCB | AL=00 rrf=# records|
- | 24 | Set random record field | DS:DX ==> FCB | |
- +----+--------------------------+-----------------------+--------------------+
- | 25 | Set interrupt vector | DS:DX = vector | Int specified in AL|
- | 26 | Create new PSP | DX = segment no. | Use 4B instead |
- +----+--------------------------+-----------------------+--------------------+
- | 27 | Random block read | DS:DX ==> FCB | CX = record count |
- | 28 | Random block write | DS:DX ==> FCB | CX = record count |
- | 29 | Parse filename | DS:SI ==> command | AL = parse service |
- +----+--------------------------+-----------------------+--------------------+
- | 2A | Get date | N/A: returns CX:DX | CX=yr DH=mo DL=day |
- | 2B | Set date | CX:DX = new date | |
- | 2C | Get time | N/A: returns CX:DX | CH=hr CL=min DH=sec|
- | 2D | Set time | CX:DX = new time | |
- | 2E | Set / reset VERIFY | DL=0, AL=1/0 (on/off | See 54 |
- +----+--------------------------+-----------------------+--------------------+
- | 2F | Get DTA | N/A: ES:BX ==>DTA | |
- |
- | 30 | Get DOS version number | N/A: returns AX | AL=major AH=minor |
- | 31 | Stay res. terminate | AL=retcode DX=size | |
- | 32 | Used internally by DOS: | | |
- | 33 | Ctrl-Break check | AL=00/01 (get/set) | |
- | | | DL=00/01 (off/on) | |
- | 34 | Used internally by DOS: | | |
- | 35 | Get interrupt vector | N/A: returns ES:BX | See 25 |
- | 36 | Get disk free space | DL=drive; returns BX | DX=tot CX=bytes |
- | | AX=sectors |
- | 37 | Used internally by DOS: | Get/set SWITCHAR | AL=0/1 DL=char |
- | 38 | Get natl dependent info | DS:DX ==> memory | country dependent |
- +----+--------------------------+-----------------------+--------------------+
- | 39 | MKDIR - Create subdir. | DS:DX ==> ASCIIZ | Errors 3,5 |
- | 3A | RMDIR - Remove subdir. | DS:DX ==> ASCIIZ | Errors 3,5 |
- | 3B | CHDIR - Change subdir. | DS:DX ==> ASCIIZ | Error 3 |
- +----+--------------------------+-----------------------+--------------------+
- | 3C | Create a file (handle) | DS:DX ==> ASCIIZ | CX=attr BX handle |
- | 3D | Open a file (handle) | DS:DX ==> ASCIIZ | AL=access code |
- | 3E | Close a file (handle) | BX = handle no. | Error 6 only |
- | 3F | Read (handle) | BX = handle no. | CX=read length |
- | 40 | Write (handle) | BX = handle no. | CX=write length |
- | 41 | Unlink - Dir. delete | DS:DX ==> ASCIIZ | Errors 2,5ength |
- | 42 | LSEEK - Move r/w pointer | BX = handle no. | AX = method |
- | | CX:DX = offset |
- | 43 | CHMOD - Change file mode | DS:DX ==> ASCIIZ | AL=function |
- | 44 | IOCTL - I/O control | BX = handle no. | AL=function value |
- | 45 | DUP - Dup file handle | BX = handle no. | AX new handle |
- | 46 | FDUP - Force dup handle | BX = handle no. | CX second handle |
- +----+--------------------------+-----------------------+--------------------+
- | 47 | Get current directory | DL = drive | DS:SI==>64byte area|
- +----+--------------------------+-----------------------+--------------------+
- | 48 | Allocate memory | BX = no. para. | AX block start |
- | 49 | Free memory | ES ==> block | Errors 7,9 |
- | 4A | Modify allocated memory | ES = block BX = size | Errors 7,8,9 |
- | 4B | EXEC - load a program | DS:DX ==>ASCIIZ | AL=function; 0 or 3|
- +----+--------------------------+-----------------------+--------------------+
- | 4C | EXIT - Terminate | AL = retcode | See FC 0 |
- | 4D | WAIT - return code | N/A: returns AX | |
- | 4E | Find first match (ASCIIZ)| DS:DX ==> ASCIIZ | CX = attrib |
- | 4F | Find next match (ASCIIZ)| DTA ==> 4E call | same as 4E |
- | 50 | Used internally by DOS: | | |
- | 51 | Used internally by DOS: | | |
- | 52 | Used internally by DOS: | | |
- | 53 | Used internally by DOS: | | |
- | 54 | Get VERIFY state | N/A: AL=0/1 (on/off) | See FC 2E |
- | 55 | Used internally by DOS: | | |
- | 56 | Rename a file (ASCIIZ)| DS:DX ==> ASCIIZ | same drive only |
- | 57 | Get/Set file date stamp | BX = handle no. | DX=date CX=time |
- | | AL = 0/1 |
- +----+--------------------------+-----------------------+--------------------+
- | AH | F U N C T I O N | Entry / Register Use | N O T E S |
- +----+--------------------------+-----------------------+--------------------+
-
- [70205,1217]
- MASM.BUG 15-Apr-84 7975 10
-
- Keywords: MASM ASSEMBLER PC-DOS BUGS
-
- This document describes some problems, omissionas, bugs and limitations
- in the IBM version of the Microsoft Macro Assembler.
-
- Disposition:
-
- <R D T): R
-
-
- The IBM / Microsoft Macro Assembler
- -
- Version 1.0
- -
- Known Problems
- -
- and
- -
- Usage Hints
- -
-
- John Chapman
-
- [70205,1217]
-
- Introduction
-
- This document describes several known limitations, bugs and quirks
- of the IBM distributed Version (1.0) of the Microsoft Assembler. Note that
- these descriptions are from various sources, and have been verified at least
- once. Some of these problems are intermittent, dependent upon available
- memory, program size, structure of source program, etc.
-
- Disclaimer
-
- Please note that this document is provided without warrantee of any
- kind. Each individual must make the final determination of applicability to
- a specific situation, program, or configuration.
-
- Audience
-
- This document is intended for the experienced assembler language
- programmer. The reader is assumed to be familiar with the 8086 instruction
- set, the IBM Macro Assembler, and the IBM Personal Computer.
-
- Additions and Corrections
-
- This document will be periodically updated as new information is
- made available. If you have corrections, or additions, please send them to:
-
- John A. Chapman
- 844 S. Madison St.
- Hinsdale, Illinois 60521
-
- Or: Send EMAIL to userid [70205,1217] on Compuserv,
- or MAIL to userid $AC on PCSHARE.
-
- Assembler Tips 2
-
- Untrapped Errors
-
- When an instruction is accepted by the assembler, it is assumed that
- the instruction is not only syntactically correct, but that it will be
- decoded, as specified, into a legal machine operation. In MASM 1.0 this
- does not always occur:
-
- Segment Registers
-
- The 8088 does not support a compare with a segment register as the
- register operand. Coding
-
- CMP ES,0
- will generate the instruction
- CMP AX,0 .... without generating a diagnostic
- message, or providing any other indication.
-
- Omitted Operands
-
- Most instructions with missing operands will generate error
- messages; the instruction:
-
- MOV AX,
- produces
-
- MOV AX,0 ... and no message
-
- Apparently, the above treatment occurs for all instructions that can
- use a register [non-segment register] with immediate data as the second
- operand. Zero is always used for the missing operand.
-
- Missing Brackets
-
- Erroneous code will also be generated if square brackets are omitted in
- certain operations, even thought an error message would be expected.
-
- MOV BYTE PTR ES:DI,'$' Is incorrect, and
- generates:
- MOV BYTE PTR ES:[7],'$' Rather than what was intended,
- which was:
- MOV BYTE PTR ES:[DI],'$'
-
- This appears to occur because the assembler finds DI in it's symbol
- table, equated to it's register triplet '111'b, and substitutes the 7 as if
- the programmer had said DI equ 7.
-
- Assembler Tips 3
-
- Data entry errors
-
- Always scan comments in a newly entered program to assure that each
- comment is preceded by a semi-colon [;], rather than a colon [:]. The
- assembler will assume that the colon denotes a label, and will subsequently
- generate the spurious message "OPEN PROCEDURES", and may generate additional
- error messages.
-
- Review program labels in failing programs: the branch table sequence
- below provides both correct and incorrect examples.
-
- Correct Incorrect
-
- JMP CS:jumlist[BX] JMP CS:jumlist[BX]
- ... ...
- ... ...
- jumlist DW routin1 jumlist: DW routin1
- DW routin2 DW routin2
-
- Radix Specifications
-
- Even if a RADIX pseudo-op has been used to specify the default base
- for data values, the assembler will still check the last character for a
- valid radix specification, and use it if present. For example:
-
- SUB BX,0B
-
- generates:
- 83 EB 00 .. which is incorrect for X'0B";
- while:
- SUB BX,11d or BX,0Bh .. are both correct;
-
- and will generate:
-
- 83 EB 0B .... which is the intended instruction.
-
- Pseudo-Operations
-
- The .XLIST pseudo operation will be ineffective [during both passes]
- if the command line parameter /D is specified for the assembly.
-
- The assembler will not correctly resolve 'identity' type definition
- errors in the EQUATE pseudo-op.
-
- LOOP-IT EQU LOOP-IT will cause the assembler to loop.
-
- Assembler Tips 4
-
- Out of Memory Error in small programs
-
- Occasionally users will experience an MASM abort with the message "OUT OF
- MEMORY", with a large amount of installed, available memory, and a small
- program. This problem is a recognized bug common to Pascal, MASM, and other
- Microsoft products written in Pascal.
-
- A>ren masm.exe masm.xxx
- A>debug masm.xxx
- -s 0 ffff 81 fb 00 10 7e 03
- xxxx:FB23
- -d fb20,fb2f
- xxxx:FB20 00
- -e FB27
- xxxx FB27 7E.76 <===================Enter 76 in response to
- first part of line
- -w
- WRITING 10800 BYTES
- -q
- A>
-
- The patch above corrects an invalid comparison for memory size, caused by
- using JLE rather than JBE for the test.
-
- Assembler Tips 5
-
- Reserved Words
-
- The IBM/Microsoft assembler documentation does not provide documentation
- on the reserved word list of the assembler. This is especially unfortunate,
- since the assembler will fail to provide a diagnostic message if a reserved
- word is used in place of an operand or label.
-
- Example:
- MOV ax,byte ;BYTE not defined - no error reported
-
- Pass 1 Errors omitted
-
- Errors caused in Pass 1 that are not repeated in pass 2 are not reported.
-
- Example:
-
- IF1
- ABC EQU AX
- ENDIF
- -- Incorrect equate - no error.
-
- Macro Parameters
-
- If a macro is invoked within another macro, with a parameter which is a
- quoted string constant, all